import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
import { StatusCodes } from 'http-status-codes';
import { AuthUser, UserRole, toAuthUser } from '../types/auth';
import { ApiError } from '../utils/ApiError';
import prisma from '../lib/prisma';

// 定义 JWT Payload 类型
export interface JwtPayload {
  userId: number;  // 改为number类型以匹配Prisma的id
  email: string;
  role: UserRole;
  exp?: number;
}

export interface AuthenticatedRequest extends Request {
  user?: AuthUser;
}

export const auth = async (
  req: AuthenticatedRequest,
  _res: Response,
  next: NextFunction
): Promise<void> => {
  try {
    const authHeader = req.headers.authorization;

    if (!authHeader?.startsWith('Bearer ')) {
      throw new ApiError(StatusCodes.UNAUTHORIZED, 'No token provided');
    }

    const token = authHeader.split(' ')[1];

    try {
      if (!process.env.JWT_SECRET || process.env.JWT_SECRET.length < 32) {
        throw new ApiError(StatusCodes.INTERNAL_SERVER_ERROR, 'Invalid JWT configuration');
      }

      const decoded = jwt.verify(token, process.env.JWT_SECRET, {
        algorithms: ['HS256']
      }) as JwtPayload;

      // 验证token是否过期
      if (decoded.exp && decoded.exp * 1000 < Date.now()) {
        throw new ApiError(StatusCodes.UNAUTHORIZED, 'Token has expired');
      }

      // 从数据库获取完整的用户信息
      const user = await prisma.user.findUnique({
        where: { id: decoded.userId }
      });

      if (!user) {
        throw new ApiError(StatusCodes.UNAUTHORIZED, 'User not found');
      }

      // 使用toAuthUser转换为AuthUser类型
      req.user = toAuthUser(user);

      next();
    } catch (error) {
      if (error instanceof jwt.TokenExpiredError) {
        throw new ApiError(StatusCodes.UNAUTHORIZED, 'Token has expired');
      } else if (error instanceof jwt.JsonWebTokenError) {
        throw new ApiError(StatusCodes.UNAUTHORIZED, 'Invalid token');
      }
      throw error;
    }
  } catch (error) {
    next(error);
  }
};
